/**
 * @file   Geometry.h
 * @author ubuntu <dadi@ubuntu>
 * @date   Tue Jun  1 14:34:37 2021
 * 
 * @brief  Define a class for Geometry, which can be a point, an edge, a surface... 
 * 
 * 
 */

#ifndef __DADI_GEOMETRY__
#define __DADI_GEOMETRY__

#include<iostream>
#include<valarray>

class Geometry;

class Geometry
{
public:
    typedef int bm_t;		/**< boundary mark type */
protected:
    size_t index;		/**< the index of the Geometry */
    bm_t boundary_mark;		/**<  */
    size_t n_dofs;
    std::valarray<size_t> vertex;
    std::valarray<size_t> boundary;
    std::valarray<int> neighbor;
    std::valarray<size_t> dofs;
public:
    /** 
     * Default constructor.
     * 
     */
    Geometry();
    virtual size_t get_index() const;
    virtual bm_t get_boundary_mark() const;
    virtual void set_index(size_t _idx);
    virtual void set_boundary_mark(bm_t _bm);
    virtual size_t get_n_vertex() const;
    virtual size_t get_n_boundary() const;
    virtual size_t get_n_neighbor() const;
    virtual size_t get_n_dofs() const;
    virtual void set_n_dofs(size_t _n);
    virtual void set_n_vertex(size_t _n);
    virtual void set_n_boundary(size_t _n);
    virtual void set_n_neighbor(size_t _n);
    virtual size_t get_vertex(size_t _i) const;
    virtual size_t get_boundary(size_t _i) const;
    virtual int get_neighbor(size_t _i) const;
    virtual size_t get_dof(size_t _i) const;
    virtual const std::valarray<size_t> &get_dof() const;
    virtual void set_vertex(size_t _i, size_t _ivtx);
    virtual void set_boundary(size_t _i, size_t _ibnd);
    virtual void set_neighbor(size_t _i, int _inei);
    virtual void set_dof(size_t _i, size_t _idof);
};

Geometry::Geometry()
{
    index = -1;   /// means no number
    boundary_mark = 0;  /// the default is an inner entity
    n_dofs = -1;
};

size_t Geometry::get_index() const
{
    return index;
};

Geometry::bm_t Geometry::get_boundary_mark() const
{
    return boundary_mark;
};

void Geometry::set_index(size_t _idx) 
{
    index = _idx;
};

void Geometry::set_boundary_mark(bm_t _bm)
{
    boundary_mark = _bm;
};

size_t Geometry::get_n_vertex() const
{
    return vertex.size();
};

size_t Geometry::get_n_boundary() const
{
    return boundary.size();
};

size_t Geometry::get_n_neighbor() const
{
    return neighbor.size();
};

size_t Geometry::get_n_dofs() const
{
    return dofs.size();
};

void Geometry::set_n_dofs(size_t _n)
{
    dofs.resize(_n);
};

void Geometry::set_n_vertex(size_t _n)
{
    vertex.resize(_n);
};

void Geometry::set_n_boundary(size_t _n)
{
    boundary.resize(_n);
};

void Geometry::set_n_neighbor(size_t _n)
{
    neighbor.resize(_n);
};

size_t Geometry::get_vertex(size_t _i) const
{
    return vertex[_i];
};

size_t Geometry::get_boundary(size_t _i) const
{
    return boundary[_i];
};

int Geometry::get_neighbor(size_t _i) const
{
    return neighbor[_i];
};

size_t Geometry::get_dof(size_t _i) const
{
    return dofs[_i];
};

const std::valarray<size_t> &Geometry::get_dof() const
{
    return dofs;
};

void Geometry::set_vertex(size_t _i, size_t _ivtx)
{
    vertex[_i] = _ivtx;
};

void Geometry::set_boundary(size_t _i, size_t _ibnd)
{
    boundary[_i] = _ibnd;
};

void Geometry::set_neighbor(size_t _i, int _inei)
{
    neighbor[_i] = _inei;
};

void Geometry::set_dof(size_t _i, size_t _idof)
{
    dofs[_i] = _idof;
};

#else
//DO NOTHING.
#endif
